/**
 * @file wnd.c
 * @brief
 * @author rock (gllier@163.com)
 * @version 2.0
 * @date 2024-02-21
 * @copyright Copyright (c) 2021 - 2024 Nanjing
 * @par History:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2024-02-21 <td>2.0     <td>rock     <td> Port to DK
 * <tr><td>2005-08-15 <td>1.0     <td>rock     <td> Create
 * </table>
 */

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "lcd_drv.h"
#include "lcd_dev.h"

#include "wnd.h"
#include "key.h"
#include "gui.h"

extern MENU MainMenu;
extern MENU SysSetMenu;
extern MENU MemTestMenu;
extern MENU TestMenu;

#define DEFAULT_BPS_SEL     1
#define MAX_BPS_SEL         8
#define DEFAULT_AREA_SEL    1
#define MAX_AREA_SEL        3
#define DEFAULT_LNG_SEL     0
#define MAX_LNG_SEL         5

static void	DefWndDisp(MENU *curmenu, unsigned char redraw, unsigned char lastitem, unsigned char curitem);

char *g_pbStrBps[]   = {
    "115200\0",
    "57600\0",
    "19200\0",
    "9600\0",
    "4800\0",
    "2400\0",
    "1200\0",
    "600\0"
};

char   *g_pbStrArea[]  = {
    "东一区\0",
    "东二区\0",
    "西一区\0"
};
char   *g_pbStrLng[]   = {
    "中 文\0",
    "英 语\0",
    "日 语\0",
    "德 语\0",
    "韩 文\0"
};
int g_bBpsSel       = DEFAULT_BPS_SEL;
int g_bBpsSelTemp   = DEFAULT_BPS_SEL;
int g_bAreaSel      = DEFAULT_AREA_SEL;
int g_bAreaSelTemp  = DEFAULT_AREA_SEL;
int g_bLngSel       = DEFAULT_LNG_SEL;
int g_bLngSelTemp   = DEFAULT_LNG_SEL;

SUBMENU(MainMenu)
LABEL(1, 1, "1.主板内存测试\0", CMD_MEMORY_TEST,    &TestMenu)
LABEL(1, 2, "2.串行通讯连接\0", CMD_UART_CONNECT,   &TestMenu)
LABEL(1, 3, "3.系统参数设置\0", CMD_SYSTEM_SET,     &SysSetMenu)
LABEL(1, 4, "4.   帮  助   \0", CMD_DEFAULT,        0)
ENDMENU(MainMenu, "【主菜单】\0", 0, 0)

SUBMENU(SysSetMenu)
LIST(0, 1, "1.波特率:", g_pbStrBps, &g_bBpsSel,	&g_bBpsSelTemp,	    MAX_BPS_SEL,	10, 1, CMD_DEFAULT, 0)
LIST(0, 2, "2.时  区:", g_pbStrArea, &g_bAreaSel, &g_bAreaSelTemp, MAX_AREA_SEL,	10, 2, CMD_DEFAULT, 0)
LIST(0, 3, "3.语  言:", g_pbStrLng, &g_bLngSel,	&g_bLngSelTemp,	   MAX_LNG_SEL,	10, 3, CMD_DEFAULT, 0)
ENDMENU(SysSetMenu, "【参数设置】\0", 0, &MainMenu)

SUBMENU(MemTestMenu)
LABEL(1, 1, "1.系统时间设置\0", CMD_DEFAULT, 0)
LABEL(1, 2, "2.通讯方式设置\0", CMD_DEFAULT, 0)
ENDMENU(MemTestMenu, "【内存测试】\0", 0, &MainMenu)

SUBMENU(TestMenu)
LABEL(1, 1, "Test menu.", CMD_DEFAULT, 0)
LABEL(1, 2, "Test menu.", 0, 0)
ENDMENU(TestMenu, "Test Title\0", 0, &MainMenu)

BEGIN_COMMAND_MAP()
ON_COMMAND(CMD_DEFAULT,	    CmdDefaultProcess,  "Default Command!\0")
ON_COMMAND(CMD_MEMORY_TEST, CmdDefaultProcess,  "Memory Test Command!\0")
ON_COMMAND(CMD_UART_CONNECT, CmdDefaultProcess, "UART Connect Command!\0")
ON_COMMAND(CMD_SYSTEM_SET,  CmdDefaultProcess,  "System Parameter Set!\0")
END_COMMAND_MAP()

MENU	*curWnd = &MainMenu;

/*
****************************************************************************************************
* Function	: 菜单处理函数
* Call Format	: DefWndProc()
* Arguments	: none
* Returns	: none
* Notes		:
* History	:		Data/Name	Note
	   		  1) 	050623/Yous	Create
	   		  2)	050701/Yous	Fix some bug and upgrade some process
	   		  3)	050815/Yous	Add and make some change
****************************************************************************************************
*/
void DefWndProc(void)
{
    int	i;
    int	j;
    int    bTabMax              = curWnd->size;
    int    bCurPos              = 0;                //光标位置
    char   bNumKey              = 0;                //是否数字键
    char   bLast                = 0;
    char   bNew                 = 0;
    int    dwKey                = GUI_KEY_INVALID;
    char   bRedraw              = REDRAW_ALL;
    static unsigned char   bCnt = 0;


    if (0 == bCnt) {
        curWnd->tab = 0x00;
        curWnd->items[curWnd->tab].tabStop	= 0x01;
        bCnt = 1;
    }
    DefWndDisp(curWnd, bRedraw, bLast, bNew);

    if (gui_get_key(&dwKey) == GUI_KEY_INVALID) {
        return;
    }
    printf("DefWndProc key = %d\n", dwKey);
    switch(dwKey) {
    case GUI_KEY_ESC:
        bNumKey	= 0;
        bRedraw = REDRAW_ALL;
        if (curWnd == &MainMenu) {
            CmdDefaultProcess(1, "Current menu is top level menu.");
            return;
        } else {
            for (i = 0; i < curWnd->size; i++) {
                if (curWnd->items[i].cls == CI_EDIT) {
                    for (j = 0; j < curWnd->items[i].editLen; j++) {
                        curWnd->items[i].editTemp[j] = curWnd->items[i].editText[j];
                    }
                } else if(curWnd->items[i].cls == CI_LIST) {
                    *curWnd->items[i].listCntTemp = *curWnd->items[i].listCnt;
                }
            }
            curWnd 		= curWnd->parent;
            bTabMax		= curWnd->size;
            for (i = 0; i < curWnd->size; i++) {
                curWnd->items[i].tabStop	= 0x00;
            }
            curWnd->items[curWnd->tab].tabStop	= 0x01;
        }/* end of else curWnd == &MainMenu */
        break;
    case GUI_KEY_ENTER:
        bNumKey	= 0;
        bRedraw = REDRAW_ALL;
        for (i = 0; i < curWnd->size; i++) {
            if (curWnd->items[i].cls == CI_EDIT) { //保存数据
                for (j = 0; j < curWnd->items[i].editLen; j++) {
                    curWnd->items[i].editText[j] = curWnd->items[i].editTemp[j];
                }
            } else if(curWnd->items[i].cls == CI_LIST) {
                *curWnd->items[i].listCnt = *curWnd->items[i].listCntTemp;
            }
        }

        if (curWnd->items[curWnd->tab].cmd != CMD_NULL) {
            OnCmdMessage(curWnd->items[curWnd->tab].cmd);
        }

        if (curWnd->items[curWnd->tab].child != MENU_NULL) {
            curWnd 	= curWnd->items[curWnd->tab].child;
            curWnd->tab	= 0;
            bTabMax	= curWnd->size;

            for (i = 0; i < bTabMax; i++) {	//清除所有焦点
                curWnd->items[i].tabStop	= 0x00;
            }

            curWnd->items[curWnd->tab].tabStop	= 0x01;

            if (curWnd->items[0].cls == CI_EDIT) {
//					CursorSetPosEx((curWnd->items[curWnd->tab].subx
//						+ bCurPos) * 6,
//						curWnd->items[curWnd->tab].suby * 12);
            }
        }
        break;
    case GUI_KEY_UP:
        bNumKey	= 0;
        bRedraw = REDRAW_ITEM;
        bLast	= curWnd->tab;
        curWnd->items[curWnd->tab].tabStop = 0x00;	//去除原焦点
        SpinValue(&curWnd->tab, 0, (unsigned char)(bTabMax - 1), 0);
        bNew	= curWnd->tab;
        curWnd->items[curWnd->tab].tabStop = 0x01;	//设置新的焦点停靠
        bCurPos	= 0;
//			CursorSetPosEx((curWnd->items[curWnd->tab].subx + bCurPos) * 6,
//						curWnd->items[curWnd->tab].suby * 12);
        break;
    case GUI_KEY_DOWN:
        bNumKey	= 0;
        bRedraw = REDRAW_ITEM;
        bLast	= curWnd->tab;
        curWnd->items[curWnd->tab].tabStop = 0x00;	//去除原焦点
        SpinValue(&curWnd->tab, 0, (unsigned char)(bTabMax - 1), 1);
        bNew	= curWnd->tab;
        curWnd->items[curWnd->tab].tabStop = 0x01;	//设置新的焦点停靠
        bCurPos	= 0;
//			CursorSetPosEx((curWnd->items[curWnd->tab].subx + bCurPos) * 6,
//						curWnd->items[curWnd->tab].suby * 12);
        break;
    case GUI_KEY_LEFT:
        bNumKey	= 0;
        if (curWnd->items[curWnd->tab].cls == CI_EDIT) {	//改变光标位置
            bRedraw = REDRAW_NO;
            SpinValue(&bCurPos, 0, (unsigned char)(curWnd->items[curWnd->tab].editLen - 1), 0);
//				CursorSetPosEx((curWnd->items[curWnd->tab].subx + bCurPos) * 6,
//						curWnd->items[curWnd->tab].suby * 12);
        } else if (curWnd->items[curWnd->tab].cls == CI_LIST) {	//更改列表选择
            bRedraw = REDRAW_ITEM;
            bLast	= curWnd->tab;
            bNew	= curWnd->tab;
            SpinValue(curWnd->items[curWnd->tab].listCntTemp, 0,
                      (unsigned char)(curWnd->items[curWnd->tab].listMax - 1), 0);
        }
        break;
    case GUI_KEY_RIGHT:
        bNumKey	= 0;
        if (curWnd->items[curWnd->tab].cls == CI_EDIT) {
            bRedraw = REDRAW_NO;
            SpinValue(&bCurPos, 0, (unsigned char)(curWnd->items[curWnd->tab].editLen - 1), 1);
//				CursorSetPosEx((curWnd->items[curWnd->tab].subx + bCurPos) * 6,
//						curWnd->items[curWnd->tab].suby * 12);
        } else if (curWnd->items[curWnd->tab].cls == CI_LIST) {
            bRedraw = REDRAW_ITEM;
            bLast	= curWnd->tab;
            bNew	= curWnd->tab;
            SpinValue(curWnd->items[curWnd->tab].listCntTemp, 0,
                      (unsigned char)(curWnd->items[curWnd->tab].listMax - 1), 1);
        }
        break;
    case GUI_KEY_NUM0:
        bNumKey = '0';
        break;
    case GUI_KEY_NUM1:
        bNumKey = '1';
        break;
    case GUI_KEY_NUM2:
        bNumKey = '2';
        break;
    case GUI_KEY_NUM3:
        bNumKey = '3';
        break;
    case GUI_KEY_NUM4:
        bNumKey = '4';
        break;
    case GUI_KEY_NUM5:
        bNumKey = '5';
        break;
    case GUI_KEY_NUM6:
        bNumKey = '6';
        break;
    case GUI_KEY_NUM7:
        bNumKey = '7';
        break;
    case GUI_KEY_NUM8:
        bNumKey = '8';
        break;
    case GUI_KEY_NUM9:
        bNumKey = '9';
        break;
    default:
        bRedraw = REDRAW_NO;
        break;
    }

    if ((bNumKey != 0) && (curWnd->items[curWnd->tab].cls == CI_EDIT)) {
        bRedraw = REDRAW_ITEM;
        bLast	= curWnd->tab;
        bNew	= curWnd->tab;
        curWnd->items[curWnd->tab].editTemp[bCurPos] = bNumKey;
        SpinValue(&bCurPos, 0, (unsigned char)(curWnd->items[curWnd->tab].editLen - 1), 1);
//		CursorSetPosEx((curWnd->items[curWnd->tab].subx + bCurPos) * 6,
//						curWnd->items[curWnd->tab].suby * 12);
    } else if ((bNumKey != 0) && (bNumKey - 0x30 <= curWnd->size)
               && (bNumKey != 0)) {
        for (i = 0; i < curWnd->tab; i++) {
            if (curWnd->items[curWnd->tab].cls != CI_LABEL) {
                break;
            }
        }

        if (i == curWnd->tab) {
            if (curWnd->items[bNumKey - 0x30 - 1].cmd != CMD_NULL) {
                OnCmdMessage(curWnd->items[bNumKey - 0x30 - 1].cmd);
            }

            if (curWnd->items[bNumKey - 0x30 - 1].child != MENU_NULL) {
                bRedraw		= REDRAW_ALL;
                curWnd->tab	= bNumKey - 0x30 - 1;
                curWnd 		= curWnd->items[curWnd->tab].child;
                curWnd->tab	= 0;
                bTabMax		= curWnd->size;

                for (i = 0; i < bTabMax; i++) {	//清除所有焦点
                    curWnd->items[i].tabStop	= 0x00;
                }

                curWnd->items[curWnd->tab].tabStop	= 0x01;

                if (curWnd->items[0].cls == CI_EDIT) {
//					CursorSetPosEx((curWnd->items[curWnd->tab].subx
//						+ bCurPos) * 6,
//						curWnd->items[curWnd->tab].suby * 12);
                }
            }
        }
    }
    DefWndDisp(curWnd, bRedraw, bLast, bNew);
}
/*
****************************************************************************************************
* Function	: 菜单显示函数
* Call Format	: DefWndDisp(curmenu,redraw,lastitem,curitem)
* Arguments	: curmenu	Current menu point
*		  redraw	Whether redraw the display
*		  lastitem	previous item count
*		  curitem	Current redraw item count
* Returns	: none
* Notes		:
* History	:		Data/Name	Note
	   		  1) 	050623/Yous	Create
*			  2)	050701/Yous	Fixed some bug and upgrade
			  3)	050815/Yous	Add
****************************************************************************************************
*/

static void	DefWndDisp(MENU *curmenu, unsigned char redraw, unsigned char lastitem, unsigned char curitem)
{
    unsigned char	i;
    unsigned char	j;

    if (redraw == REDRAW_ALL) {
        lcd_clear(LCD_BACK_COLOR);
        lcd_put_str16((GUI_CHAR_X_MAX - strlen(curmenu->title)) / 2, 0, curmenu->title, LCD_DISPLAY_NORMAL);

        for (i = 0; i < curmenu->size; i++) {
            if (curmenu->items[i].tabStop) {
                lcd_put_str16(curmenu->items[i].x, curmenu->items[i].y, curmenu->items[i].labelText, LCD_DISPLAY_RESVERSE);
            } else {
                lcd_put_str16(curmenu->items[i].x, curmenu->items[i].y, curmenu->items[i].labelText, LCD_DISPLAY_NORMAL);
            }

            if (curmenu->items[i].cls == CI_EDIT) {
                for (j = 0; j < curmenu->items[i].editLen; j++) {
//					goxy(curmenu->items[i].subx + j,curmenu->items[i].suby);
//					printfEx(curmenu->items[i].editTemp[j]);
                }
            } else if (curmenu->items[i].cls == CI_LIST) {
                lcd_put_str16(curmenu->items[i].subx, curmenu->items[i].suby,
                              curmenu->items[i].listTable[*curmenu->items[i].listCntTemp],
                              0);
            }
        }
    } else if (redraw == REDRAW_ITEM) {
        if (lastitem != curitem) {
            if (curmenu->items[lastitem].tabStop) {
                lcd_put_str16(curmenu->items[lastitem].x,
                              curmenu->items[lastitem].y,
                              curmenu->items[lastitem].labelText,
                              LCD_DISPLAY_RESVERSE);
            } else {
                lcd_put_str16(curmenu->items[lastitem].x,
                              curmenu->items[lastitem].y,
                              curmenu->items[lastitem].labelText,
                              LCD_DISPLAY_NORMAL);
            }
            if (curmenu->items[curitem].tabStop) {
                lcd_put_str16(curmenu->items[curitem].x,
                              curmenu->items[curitem].y,
                              curmenu->items[curitem].labelText,
                              LCD_DISPLAY_RESVERSE);
            } else {
                lcd_put_str16(curmenu->items[curitem].x,
                              curmenu->items[curitem].y,
                              curmenu->items[curitem].labelText,
                              LCD_DISPLAY_NORMAL);
            }
        } else {
            if (curmenu->items[curitem].cls == CI_EDIT) {
                for (j = 0; j < curmenu->items[curitem].editLen; j++) {
//					goxy(curmenu->items[curitem].subx + j,curmenu->items[curitem].suby);
//					printfEx(curmenu->items[curitem].editTemp[j]);
                }
//				CursorSetStatusEx(CURSOR_ON);
//				CursorSetStatusEx(CURSOR_REVERSED);
            } else if (curmenu->items[curitem].cls == CI_LIST) {
                lcd_put_str16(curmenu->items[curitem].subx, curmenu->items[curitem].suby,
                              curmenu->items[curitem].listTable[*curmenu->items[curitem].listCntTemp],
                              LCD_DISPLAY_NORMAL);
            }
        }
    }
}


/*
****************************************************************************************************
* Function	: 命令响应处理
* Call Format	: OnCmdMessage()
* Arguments	: cmd	需要响应的命令
* Returns	: 0 - 成功, -1 - 失败
* Notes		:
* History	:		Data/Name	Note
	   		  1) 	050624/Yous	Create
	   		  2)	050816/Yous	Add
****************************************************************************************************
*/
int OnCmdMessage(int cmd)
{
    const CMDMAP *pEntries;

    if (cmd == CMD_NULL) {
        return 0;
    }

    pEntries = GetCommandMap();

    while ((pEntries->cmd) && (pEntries->cmd != cmd)) {
        pEntries ++;
    }

    if ( !(pEntries->cmd) || !(pEntries->pf) ) {
        return -1;
    }

    (*pEntries->pf)((unsigned int)cmd, pEntries->pbName);

    return 0;
}
